# -*- coding: utf-8 -*-
"""
积分系统 - 视图函数
"""

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.utils import timezone
from django.db import transaction
from .models import PointProduct, PointExchange, PointRecord, DailyCheckin
from datetime import date, timedelta
import json


def shop(request):
    """积分商城页面"""
    return render(request, 'points/shop.html')


@login_required
def records(request):
    """积分记录页面"""
    return render(request, 'points/records.html')


@login_required
def exchanges(request):
    """兑换记录页面"""
    return render(request, 'points/exchanges.html')


@login_required
def checkin(request):
    """每日签到页面"""
    return render(request, 'points/checkin.html')


# ========== API视图 ==========

@require_http_methods(["GET"])
def api_products_list(request):
    """获取积分商品列表API"""
    products = PointProduct.objects.filter(status='available').order_by('-sort_order', '-created_at')
    
    # 类型筛选
    product_type = request.GET.get('type')
    if product_type:
        products = products.filter(type=product_type)
    
    results = [{
        'id': p.id,
        'name': p.name,
        'description': p.description,
        'image': p.image,
        'type': p.type,
        'points_required': p.points_required,
        'stock': p.stock,
        'exchange_count': p.exchange_count,
        'limit_per_user': p.limit_per_user,
        'status': p.status,
    } for p in products]
    
    return JsonResponse({
        'code': 200,
        'data': {
            'results': results
        }
    })


@login_required
@require_http_methods(["POST"])
def api_exchange_product(request, product_id):
    """兑换商品API"""
    try:
        product = get_object_or_404(PointProduct, id=product_id)
        data = json.loads(request.body)
        quantity = data.get('quantity', 1)
        
        # 检查库存
        if product.stock < quantity:
            return JsonResponse({
                'code': 400,
                'message': '库存不足'
            }, status=400)
        
        # 检查积分
        total_points = product.points_required * quantity
        if request.user.points < total_points:
            return JsonResponse({
                'code': 400,
                'message': '积分不足'
            }, status=400)
        
        # 检查兑换限制
        if product.limit_per_user > 0:
            user_exchanged = PointExchange.objects.filter(
                user=request.user,
                product=product
            ).count()
            if user_exchanged >= product.limit_per_user:
                return JsonResponse({
                    'code': 400,
                    'message': f'每人限兑{product.limit_per_user}次'
                }, status=400)
        
        # 创建兑换记录
        exchange = PointExchange.objects.create(
            user=request.user,
            product=product,
            points_spent=total_points,
            quantity=quantity,
            receiver_name=data.get('receiver_name', ''),
            receiver_phone=data.get('receiver_phone', ''),
            receiver_address=data.get('receiver_address', ''),
            status='pending'
        )
        
        # 扣除积分
        request.user.points -= total_points
        request.user.save(update_fields=['points'])
        
        # 创建积分记录
        PointRecord.objects.create(
            user=request.user,
            points=-total_points,
            type='spend_exchange',
            description=f'兑换商品：{product.name}',
            related_product=product,
            balance_after=request.user.points
        )
        
        # 更新商品库存和兑换次数
        product.stock -= quantity
        product.exchange_count += quantity
        product.save(update_fields=['stock', 'exchange_count'])
        
        return JsonResponse({
            'code': 200,
            'message': '兑换成功'
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'兑换失败：{str(e)}'
        }, status=500)


@login_required
@require_http_methods(["GET"])
def api_point_records(request):
    """获取积分记录API"""
    records = PointRecord.objects.filter(user=request.user).order_by('-created_at')
    
    page = int(request.GET.get('page', 1))
    page_size = int(request.GET.get('page_size', 20))
    
    start = (page - 1) * page_size
    end = start + page_size
    total = records.count()
    
    results = [{
        'id': r.id,
        'points': r.points,
        'type': r.type,
        'type_display': r.get_type_display(),
        'description': r.description,
        'balance_after': r.balance_after,
        'created_at': r.created_at.isoformat(),
    } for r in records[start:end]]
    
    return JsonResponse({
        'code': 200,
        'data': {
            'results': results,
            'count': total,
            'page': page,
        }
    })


@login_required
@require_http_methods(["GET"])
def api_exchange_records(request):
    """获取兑换记录API"""
    exchanges = PointExchange.objects.filter(user=request.user).select_related('product').order_by('-created_at')
    
    results = [{
        'id': e.id,
        'product': {
            'id': e.product.id,
            'name': e.product.name,
            'image': e.product.image,
        },
        'points_spent': e.points_spent,
        'quantity': e.quantity,
        'status': e.status,
        'status_display': e.get_status_display(),
        'created_at': e.created_at.isoformat(),
    } for e in exchanges]
    
    return JsonResponse({
        'code': 200,
        'data': {
            'results': results
        }
    })


# ========== 签到相关API ==========

@login_required
@require_http_methods(["POST"])
def api_checkin(request):
    """执行每日签到API"""
    try:
        today = date.today()
        
        # 检查今天是否已签到
        if DailyCheckin.has_checked_in_today(request.user):
            return JsonResponse({
                'code': 400,
                'message': '今天已经签到过了'
            }, status=400)
        
        # 计算连续签到天数
        yesterday = today - timedelta(days=1)
        yesterday_checkin = DailyCheckin.objects.filter(
            user=request.user,
            checkin_date=yesterday
        ).first()
        
        consecutive_days = 1
        if yesterday_checkin:
            consecutive_days = yesterday_checkin.consecutive_days + 1
        
        # 计算获得的积分（连续签到奖励）
        base_points = 5
        if consecutive_days >= 7:
            points_earned = base_points + 10  # 连续7天额外奖励10积分
        elif consecutive_days >= 3:
            points_earned = base_points + 5   # 连续3天额外奖励5积分
        else:
            points_earned = base_points
        
        # 使用事务确保数据一致性
        with transaction.atomic():
            # 创建签到记录
            checkin = DailyCheckin.objects.create(
                user=request.user,
                checkin_date=today,
                points_earned=points_earned,
                consecutive_days=consecutive_days
            )
            
            # 增加用户积分
            request.user.points += points_earned
            request.user.save(update_fields=['points'])
            
            # 创建积分记录
            PointRecord.objects.create(
                user=request.user,
                points=points_earned,
                type='earn_checkin',
                description=f'每日签到奖励（连续{consecutive_days}天）',
                balance_after=request.user.points
            )
        
        return JsonResponse({
            'code': 200,
            'message': '签到成功！',
            'data': {
                'points_earned': points_earned,
                'consecutive_days': consecutive_days,
                'total_points': request.user.points
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'签到失败：{str(e)}'
        }, status=500)


@login_required
@require_http_methods(["GET"])
def api_checkin_status(request):
    """获取签到状态API"""
    today = date.today()
    has_checked_in = DailyCheckin.has_checked_in_today(request.user)
    consecutive_days = DailyCheckin.get_user_consecutive_days(request.user)
    
    # 获取本月签到记录
    month_start = date(today.year, today.month, 1)
    month_checkins = DailyCheckin.objects.filter(
        user=request.user,
        checkin_date__gte=month_start,
        checkin_date__lte=today
    ).count()
    
    return JsonResponse({
        'code': 200,
        'data': {
            'has_checked_in': has_checked_in,
            'consecutive_days': consecutive_days,
            'month_checkins': month_checkins,
            'total_points': request.user.points
        }
    })


@login_required
@require_http_methods(["GET"])
def api_checkin_calendar(request):
    """获取签到日历数据API"""
    # 获取年月参数，默认当前月
    year = int(request.GET.get('year', date.today().year))
    month = int(request.GET.get('month', date.today().month))
    
    # 计算月份范围
    month_start = date(year, month, 1)
    if month == 12:
        month_end = date(year + 1, 1, 1) - timedelta(days=1)
    else:
        month_end = date(year, month + 1, 1) - timedelta(days=1)
    
    # 获取该月的签到记录
    checkins = DailyCheckin.objects.filter(
        user=request.user,
        checkin_date__gte=month_start,
        checkin_date__lte=month_end
    ).order_by('checkin_date')
    
    # 构建日历数据
    checkin_dates = []
    for checkin in checkins:
        checkin_dates.append({
            'date': checkin.checkin_date.strftime('%Y-%m-%d'),
            'points': checkin.points_earned,
            'consecutive_days': checkin.consecutive_days
        })
    
    return JsonResponse({
        'code': 200,
        'data': {
            'year': year,
            'month': month,
            'checkins': checkin_dates
        }
    })
